package com.yonyougov.devops.cruxcisupport.rancher;

import com.yonyougov.devops.cruxcisupport.app.AppDao;
import com.yonyougov.devops.cruxcisupport.app.AppEntity;
import com.yonyougov.devops.cruxcisupport.appenv.AppEnvPortDao;
import com.yonyougov.devops.cruxcisupport.appenv.AppEnvService;
import com.yonyougov.devops.cruxcisupport.appenv.dto.AppEnvPageLikeDbParams;
import com.yonyougov.devops.cruxcisupport.appenv.vo.AppEnvPageVo;
import com.yonyougov.devops.cruxcisupport.appenvconfigitem.AppEnvConfigItemDao;
import com.yonyougov.devops.cruxcisupport.appenvconfigitem.AppEnvConfigItemEntity;
import com.yonyougov.devops.cruxcisupport.appenvport.AppEnvPortEntity;
import com.yonyougov.devops.cruxcisupport.rancher.namespace.RhNameSpace;
import com.yonyougov.devops.cruxcisupport.rancher.service.RhServicePort;
import com.yonyougov.devops.cruxcisupport.rancher.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class RancherServiceImpl implements RancherService {
    private final RancherDao rancherDao;
    private final AppEnvService appEnvService;
    private final AppEnvPortDao appEnvPortDao;
    private final AppEnvConfigItemDao appEnvConfigItemDao;
    private final AppDao appDao;

    public RancherServiceImpl(RancherDao rancherDao, AppEnvService appEnvService, AppEnvPortDao appEnvPortDao, AppEnvConfigItemDao appEnvConfigItemDao, AppDao appDao) {
        this.rancherDao = rancherDao;
        this.appEnvService = appEnvService;
        this.appEnvPortDao = appEnvPortDao;
        this.appEnvConfigItemDao = appEnvConfigItemDao;
        this.appDao = appDao;
    }

    @Override
    public boolean createPod(CreatePodRequestVo createPodRequestVo) {
        //查看pod是否已经存在
        RhProject rhProject = rancherDao.getProject(createPodRequestVo.getEnvName());
        if (null == rhProject) {
            log.info("cluster {} don't e xist", createPodRequestVo.getEnvName());
            return false;
        }
        //获取健康检查路径
        AppEntity appEntity = new AppEntity();
        appEntity.setApp(createPodRequestVo.getAppName());
        AppEntity app = appDao.findBy(appEntity);
        createPodRequestVo.setHealthCheckPath(app.getHealthCheckPath());

        String id = rhProject.getId();
        String name = rhProject.getName();
        log.info("cluster : {} is : {}", name, id);
        RhDeployment deployment = rancherDao.getDeployment(id, createPodRequestVo.getAppName());
        if (null != deployment) {
            log.info("deployment is exist.Need to remove it!");
            rancherDao.deletePod(name, createPodRequestVo.getAppName(), id);
            //删除service
            rancherDao.deleteService(id, createPodRequestVo.getEnvName(), createPodRequestVo.getAppName() + "-svc");
            //只要pod完全删除,和service完全删除后，创建新的
            // 需要完整的机制，目前这里等.30s处理
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {

            }
        }
        boolean createPodResult = rancherDao.createPod(rhProject.getId(), createPodRequestVo);
        if (createPodResult) {
            //获取nameSpace信息
            String clusterId = rhProject.getClusterId();
            log.info("clusterId is : {} ", clusterId);
            RhNameSpace rhNameSpace = rancherDao.getRhNameSpace(clusterId, name);
            //创建service
            rancherDao.createPodService(id, createPodRequestVo, rhNameSpace);
            //删除rancher创建deployment自带的service
            // 应该等pod的状态为Running时删除自带的service,目前等待15秒处理
            try {
                Thread.sleep(15000);
            } catch (InterruptedException e) {

            }
            //删除自带的service
            rancherDao.deleteService(id, createPodRequestVo.getEnvName(), createPodRequestVo.getAppName());
        }
        return true;
    }

    @Override
    public boolean createCluster(CreateClusterRequestVo request) {
        //获取集群名称
        String clusterName = request.getClusterName();
        //获取端口范围
        String portRange = request.getPortRange();
        return rancherDao.createCluster(clusterName, portRange);
    }

    @Override
    public String getCmdToAddNodes(GetCmdToAddNodesRequestVo request) {
        String envName = request.getEnvName();
        String roles = request.getRoles();
        return rancherDao.getCmdToAddNodes(envName, roles);
    }

    @Override
    public boolean deployAllPodByEnvName(String envName) {
        AppEnvPageLikeDbParams params = new AppEnvPageLikeDbParams();
        params.setEnvName(envName);
        params.setPageAble(false);
        List<AppEnvPageVo> data = appEnvService.findAppEnvLikePage(params).get("data");
        List<CreatePodRequestVo> createPodRequestVoList = new ArrayList<>();
        data.forEach(appEnvPageVo -> {
            CreatePodRequestVo createPodRequestVo = new CreatePodRequestVo();
            createPodRequestVo.setAppName(appEnvPageVo.getAppName());
            createPodRequestVo.setEnvName(appEnvPageVo.getEnvName());
            createPodRequestVo.setImage(appEnvPageVo.getImage());
            createPodRequestVo.setPackageVersion(appEnvPageVo.getPackageVersion());
            //获取端口映射
            AppEnvPortEntity appEnvPortEntity = new AppEnvPortEntity();
            appEnvPortEntity.setPageAble(false);
            appEnvPortEntity.setAppEnvId(appEnvPageVo.getId());
            List<AppEnvPortEntity> appEnvPortEntities = appEnvPortDao.findAllBy(appEnvPortEntity);
            List<RhServicePort> rhServicePorts = new ArrayList<>();
            appEnvPortEntities.forEach(appEnvPort -> {
                RhServicePort rhServicePort = new RhServicePort();
                rhServicePort.setName(appEnvPort.getName());
                rhServicePort.setPort(String.valueOf(appEnvPort.getPort()));
                rhServicePort.setTargetPort(String.valueOf(appEnvPort.getPort()));
                rhServicePort.setNodePort(String.valueOf(appEnvPort.getMappingPort()));
                rhServicePorts.add(rhServicePort);
            });
            createPodRequestVo.setPorts(rhServicePorts);
            //获取环境变量
            Map<String, String> environment = new HashMap<>();
            AppEnvConfigItemEntity appEnvConfigItemEntity = new AppEnvConfigItemEntity();
            appEnvConfigItemEntity.setPageAble(false);
            appEnvConfigItemEntity.setAppEnvId(appEnvPageVo.getId());
            List<AppEnvConfigItemEntity> appEnvConfigItemEntities = appEnvConfigItemDao.findAllBy(appEnvConfigItemEntity);
            appEnvConfigItemEntities.forEach(appEnvConfigItem ->
                    environment.put(appEnvConfigItem.getName(), appEnvConfigItem.getValue())
            );
            createPodRequestVo.setEnvironment(environment);
            createPodRequestVoList.add(createPodRequestVo);
        });
        createPodRequestVoList.forEach(createPodRequestVo -> createPod(createPodRequestVo));
        return true;
    }
}
